/**
 * PeerSamplingService.java
 * ************************** 
 * @date Mar 18, 2011
 * @author Michele Tamburini
 * 
 * **************************
 */
package gossipServices.pss;

import gossipServices.basic.nodeDescriptors.NodeDescriptor;
import gossipServices.basic.view.PartialView;
import gossipServices.basic.view.PartialView.PEER_SELECTION_ENUM;
import gossipServices.gossipThread.ActiveGossipThread;
import gossipServices.gossipThread.GossipBasedProtocol;
import gossipServices.gossipThread.PassiveGossipThread;

/**
 * 
 * Description:
 * This is a general class for the Peer Sampling Service that extends
 * the GossipBasedProtocol, so it's able to launch the active and 
 * passive thread.
 * 
 * Please refere to:
 * "Gossip-based Peer Sampling", M. Jelasity, S. Voulgaris, 
 * R. Guerraoui, A. Kermarrec, M. Van Steen,
 * for a complete description of this service.
 *
 */
public abstract class PeerSamplingService extends GossipBasedProtocol 
		implements PeerSamplingServiceAPI{

	/**
	 * 
	 * Description:
	 * Defines the method by which subsets of the PartialView
	 * are spread among peers.
	 * push: the peer pushes its own view to another one;
	 * pushpull: the peer pushes a subset of its own view 
	 * 			 to a selected peer (push phase),
	 * 			 and receives as answer a subset of the PartialView from the 
	 * 			 selected peer (pull phase).
	 */
	public static enum VIEW_PROPAGATION_ENUM {push, pushpull};
	protected boolean push = true;
	protected boolean pull;
	
	/**
	 * The PartialView used by the Peer Sampling Service.
	 */
	protected PartialView view;
		

	protected GossipBasedProtocol gossipProtocol;
	
	/**
	 * c = the size of the PartialView.
	 * The implementation must ensure that 
	 * the PartialView is at least of size 'c' during each operation.
	 */
	protected int c;
	
	/**
	 * H = the Healer ratio of the NodeDescriptor(s) kept into the PartialView.
	 */
	protected int H;
	
	/**
	 * S = the Swapper ratio of the NodeDescriptor(s) kept into the PartialView.
	 */
	protected int S;
		
	/**
	 * Defines the peer selection mechanism performed by the selectPeer.
	 * May be:
	 *  rand = random, or 
	 *  tail = tail element from the PartialView.
	 */
	protected PEER_SELECTION_ENUM peerSelection = PEER_SELECTION_ENUM.rand;
	
	public PeerSamplingService(){
		super();
	}

	/**
	 * @param activeThread
	 * @param passiveThread
	 */
	public PeerSamplingService(ActiveGossipThread activeThread,
			PassiveGossipThread passiveThread) {
		super(activeThread, passiveThread);
	}

	public final GossipBasedProtocol getGossipProtocol() {
		return gossipProtocol;
	}

	public final void setGossipProtocol(GossipBasedProtocol gossipProtocol) {
		this.gossipProtocol = gossipProtocol;
	}

	@Override
	public NodeDescriptor getPeer() {
		return view.selectPeer(peerSelection);
	}
	
	public void setViewSize(int viewSize){
		c = viewSize;
	}
	
	public int getViewSize(){
		return c;
	}
	
	public void setSwappedDescriptors_S(int S){
		this.S = S;
	}
	
	public void setHealerDescriptors_H(int H){
		this.H = H;
	}
	
	public void setViewPropagation_Push(){
		push = true;
		pull = false;
	}
	
	public void setViewPropagation_PushPull(){
		push = true;
		pull = true;
	}
	
	@Override
	public PartialView accessPartialView(){
		return view;
	}

}
